import type { AxiosInstance, AxiosRequestConfig } from 'axios';
import { getToken } from '@/common/utils/cache/cookies.ts';
import axios from 'axios';
import { get, merge } from 'lodash-es';
import { useUserStore } from '@/store/modules/user.ts';
import { throttle } from 'lodash';

/** 退出登录并强制刷新页面（会重定向到登录页） */
function logout() {
  useUserStore().logout();
}

/** 对token不存在提示信息进行节流 */
const showMessage = throttle(
  (message) => {
    ElMessage.error(message);
  },
  300,
  { trailing: false }
);

/** 创建请求实例 */
function createInstance() {
  // 创建一个 axios 实例命名为 instance
  const instance = axios.create();
  // 请求拦截器
  instance.interceptors.request.use(
    // 发送之前
    (config) => config,
    // 发送失败
    (error) => Promise.reject(error)
  );
  // 响应拦截器（可根据具体业务作出相应的调整）
  instance.interceptors.response.use(
    (response) => {
      // apiData 是 api 返回的数据
      const apiData = response.data;
      // 二进制数据则直接返回
      const responseType = response.request?.responseType;
      if (responseType === 'blob' || responseType === 'arraybuffer')
        return apiData;
      const code = apiData.code;
      switch (code) {
        case 200:
          return apiData;
        case 400:
          ElMessage({
            message: `${apiData.message}`,
            type: 'warning',
          });
          break;
        case 401:
          // Token 过期时
          showMessage(apiData.message || '未授权');
          logout();
          break;
        case 500:
          showMessage(apiData.message || '服务器内部错误');
          break;
        default:
      }
    },
    (error) => {
      // status 是 HTTP 状态码
      const status = get(error, 'response.status');
      const message = get(error, 'response.data.message');
      switch (status) {
        case 400:
          error.message = '请求错误';
          break;
        case 401:
          // Token 过期时
          error.message = message || '未授权';
          logout();
          break;
        case 403:
          error.message = message || '拒绝访问';
          break;
        case 404:
          error.message = '请求地址出错';
          break;
        case 408:
          error.message = '请求超时';
          break;
        case 500:
          error.message = '服务器内部错误';
          break;
        case 501:
          error.message = '服务未实现';
          break;
        case 502:
          error.message = '网关错误';
          break;
        case 503:
          error.message = '服务不可用';
          break;
        case 504:
          error.message = '网关超时';
          break;
        case 505:
          error.message = 'HTTP 版本不受支持';
          break;
      }
      ElMessage.error(error.message);
      return Promise.reject(error);
    }
  );
  return instance;
}

/** 创建请求方法 */
function createRequest(instance: AxiosInstance) {
  return <T>(config: AxiosRequestConfig): Promise<T> => {
    const token = getToken();
    // 默认配置
    const defaultConfig: AxiosRequestConfig = {
      // 接口地址
      baseURL: import.meta.env.VITE_API_BASE_URL,
      // 请求头
      headers: {
        // 只在有 token 时设置 Authorization
        ...(token && { Authorization: `${token}` }),
        'Content-Type': 'application/json',
      },
      // 请求体
      data: {},
      // 请求超时
      timeout: 5000,
      // 跨域请求时是否携带 Cookies
      withCredentials: false,
    };
    // 将默认配置 defaultConfig 和传入的自定义配置 config 进行合并成为 mergeConfig
    const mergeConfig = merge(defaultConfig, config);
    return instance(mergeConfig);
  };
}

/** 用于请求的实例 */
const instance = createInstance();

/** 用于请求的方法 */
export const request = createRequest(instance);
